package com.iu.shiro.realm;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.iu.bean.author.User;
import com.iu.service.author.UserService;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-1-28
 * <p>Version: 1.0
 */
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String)principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(userService.findRoles(username));
        authorizationInfo.setStringPermissions(userService.findPermissions(username));

        return authorizationInfo;
    }

    /**
     * 验证用户信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String username = (String)token.getPrincipal();

        User user = userService.findByUsername(username);

        if(user == null) {
            throw new UnknownAccountException();//没找到帐号
        }

        if(Boolean.TRUE.equals(user.getLocked())) {
            throw new LockedAccountException(); //帐号锁定
        }

        //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user.getUsername(), //用户名
                user.getPassword(), //密码
                ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt
                getName()  //realm name
        );
        return authenticationInfo;
    }
    
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        String url = null;
        String user = null;
        String password = null;
        String sql = null;
        try {
         Class.forName("com.mysql.jdbc.Driver"); //加载mysq驱动
        } catch (ClassNotFoundException e) {
         System.out.println("驱动加载错误");
         e.printStackTrace();//打印出错详细信息
        }
        try {
         url = 
          "jdbc:mysql://localhost:3306/iu?user=root&password=root&useUnicode=true&&characterEncoding=gb2312&autoReconnect = true";//简单写法：url = "jdbc:myqsl://localhost/test(数据库名)? user=root(用户)&password=yqs2602555(密码)";
         user = "root";
         password = "root";
         conn = DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
         System.out.println("数据库链接错误");
         e.printStackTrace();
        }
        try {
         stmt = conn.createStatement();
         sql = "select * from sys_permissions";//dept这张表有deptno，deptname和age这三个字段
         rs = stmt.executeQuery(sql);//执行sql语句
        } catch (SQLException e) {
         System.out.println("数据操作错误");
         e.printStackTrace();
        }
      //关闭数据库
        try {
         if(rs != null) {
          rs.close();
          rs = null;
         }
         if(stmt != null) {
          stmt.close();
          stmt = null;
         }
         if(conn != null) {
          conn.close();
          conn = null;
         }
        } catch(Exception e) {
         System.out.println("数据库关闭错误");
         e.printStackTrace();
        }
       }
}
